package server

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"net"
	"time"

	"ifile/utils"
)

type Handler interface {
	Handle(conn net.Conn, head []byte) error
}

type TCPServer struct {
	Address string
}

func MakeTCPServer(address string) *TCPServer {
	return &TCPServer{
		Address: address,
	}
}

// Decode 解析消息头
func (s *TCPServer) decode(reader *bufio.Reader) ([]byte, error) {
	lenByte := make([]byte, 4)
	_, err := reader.Read(lenByte)
	if err != nil {
		return nil, err
	}

	lenHead := utils.BytesToInt(lenByte)

	head := make([]byte, lenHead)
	_, err = reader.Read(head)
	if err != nil {
		log.Println("消息读取失败! err:", err)
		return nil, err
	}

	return head, nil
}

// ListenAndServe 监听服务
func (s *TCPServer) ListenAndServe(handler Handler) {
	listener, err := net.Listen("tcp", s.Address)
	if err != nil {
		log.Fatal(fmt.Sprintf("listen err: %v", err))
	}
	defer listener.Close()
	log.Println(fmt.Sprintf("bind: %s, start listening...", s.Address))

	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Fatal(fmt.Sprintf("accept err: %v", err))
		}
		log.Printf("创建新连接. 来自客户端: %v", conn.RemoteAddr())

		go s.connHandle(conn, handler)
	}
}

func (s *TCPServer) connHandle(conn net.Conn, handler Handler) {
	defer conn.Close()
	reader := bufio.NewReader(conn)

	for {
		head, err := s.decode(reader)
		if err != nil {
			if err == io.EOF {
				log.Printf("连接关闭. 客户端: %v", conn.RemoteAddr())
				break
			}
			// TODO 连接超时处理
			time.Sleep(time.Duration(1) * time.Second)
			continue
		} else {
			conn.Write([]byte("OK"))
		}

		err = handler.Handle(conn, head)
		if err != nil {
			log.Printf("数据接收处理错误！")
			break
		}
	}
}
